package Improvement;

import java.util.ArrayList;
import java.util.List;

import XmlLoader.FGObjProcess;
import XmlLoader.FGObjectTrajectoryStructure;
import XmlLoader.Position;
import Application.ImageGenerator;
import Application.ReadFileGenerateor;
import Cluster.ClusterBulk;
import Cluster.Trajectory;
import Cluster.Vector;
import MyLoader.MyLoader;

class ele {
	int index = 0;
	double entropy = 0;
	public ele(int index, double entropy) {
		this.index = index;
		this.entropy = entropy;
	}
}

public class Entropy {
	
	protected int intervalAngle = 0;
	protected int gridSize = 0;
	ArrayList<ele> listSortTrajId = new ArrayList<ele>();
	
	public Entropy(int intervalAngle, int gridSize) {
		this.intervalAngle = intervalAngle;
		this.gridSize = gridSize;
	}

	public double ACT001_countEntropyDirection(GridTraj traj) {
		double value = 0.0;
		double[] classfi_angle = new double[360/this.intervalAngle];
		double[] weight = new double[360/this.intervalAngle];
		Vector v_target = new Vector(0,0,0,1);
		//initial each bulk
		int index = 0;
		while(index < classfi_angle.length) {
			classfi_angle[index] = 0;
			weight[index] = 0;
			index = index + 1;
		}
		//count total distance of traj
		double distTraj = traj.GET001_element(0).pos.ACT001_countDist(traj.GET001_element(traj.GET002_length() - 1).pos);
		//do classification
		Vector v_first = null, v_second = null, v_new = null;
		index = 1;
		while(index < traj.GET002_length()) {
			v_new = new Vector(traj.GET001_element(index-1).pos.x, traj.GET001_element(index-1).pos.y, 
					traj.GET001_element(index).pos.x - traj.GET001_element(index-1).pos.x, 
					traj.GET001_element(index).pos.y - traj.GET001_element(index-1).pos.y);
			if(v_first == null) {
				v_first = v_new;
			}
			else {
				v_second = v_new;
				double angle1 = v_target.ACT001_countAngle(v_first);
				double angle2 = v_target.ACT001_countAngle(v_second);
				double angle = Math.abs(angle2 - angle1);
				classfi_angle[(int)angle/this.intervalAngle] = classfi_angle[(int)angle/this.intervalAngle] + 1;
				
				weight[(int)angle/this.intervalAngle] = weight[(int)angle/this.intervalAngle] + v_second.getEndPos().ACT001_countDist(v_second.getStartPos());
				v_first = v_second;
			}
			index = index + 1;
		}
		//count total value
		double total = 0.0;
		double total_weight = 0.0;
		index = 0;
		while(index < classfi_angle.length) {
			total = total + classfi_angle[index];
			total_weight = total_weight + weight[index];
			index = index + 1;
		}
		//count entropy
		index = 0;
		while(index < classfi_angle.length) {
			System.out.println(classfi_angle[index] + " " + weight[index]);
			if(classfi_angle[index] > 0) {
				double temp = (double)classfi_angle[index] / total;
				value = value + (((-(temp) * Math.log10(temp) / Math.log10(2))) * weight[index] / total_weight);
			}
			index = index + 1;
		}
		return value;
	}
	
	public double ACT001_countEntropyBbox(GridTraj traj) {
		double value = 0.0;
		
		return value;
	}
	
	public void ACT002_insert(int trajId, double valueEntropy) {
		int index = 0;
		boolean isFound = false;
		ele newEle = new ele(trajId, valueEntropy);
		while(!isFound && index < this.listSortTrajId.size()){
			ele getEle = this.listSortTrajId.get(index);
			if(newEle.entropy < getEle.entropy) {
				this.listSortTrajId.add(index, newEle);
				isFound = true;
			}
			index = index + 1;
		}
		if(!isFound) {
			this.listSortTrajId.add(newEle);
		}
	}
	
	public static void main(String[] args) {
		//generate list trajectory index
		System.out.println("Generate trajectory index file");
		new ReadFileGenerateor().ACT001_genFile(args[0], Integer.parseInt(args[1]), Integer.parseInt(args[2]));
		
		//load trajectory xml data
		System.out.println("Load trajectory xml file");
		FGObjProcess fgObj = new FGObjProcess(args[3]);
		List<String> list_objIndex = fgObj.ACT004_getStringList(args[0]);
		List<FGObjectTrajectoryStructure> listAll = new MyLoader().ACT001_getListOfObj(args[3], list_objIndex);
		
		//trajectory structure transformation
		ArrayList<GridTraj> listTraj = new ArrayList<GridTraj>();
		int index = 0;
		while(index < listAll.size()) {
			listTraj.add(new GridTraj(listAll.get(index), 30, null));
			index = index + 1;
		}
		
		Entropy e = new Entropy(30,30);
		index = 0;
		while(index < listTraj.size()) {
			e.ACT002_insert(index, e.ACT001_countEntropyDirection(listTraj.get(index)));
			index = index + 1;
		}
		
		//trajectory structure transformation
		ArrayList<Trajectory> listTrajOld = new ArrayList<Trajectory>();
		index = 0;
		while(index < listAll.size()) {
			listTrajOld.add(new Trajectory(listAll.get(index), 0, 0, listAll.get(index).GET002_nNumberOfPoint()));
			index = index + 1;
		}
				
		ClusterBulk cb = new ClusterBulk(0, -1);
		
		index = 0;
		while(index < e.listSortTrajId.size()) {
			cb.ACT001_insertNewTraj(listTrajOld.get(e.listSortTrajId.get(index).index));
			System.out.println(e.listSortTrajId.get(index).index + " " + e.listSortTrajId.get(index).entropy);
			index = index + 1;
		}
		ArrayList<ClusterBulk> listCb = new ArrayList<ClusterBulk>();
		listCb.add(cb);
		
		ImageGenerator.GenClusterOneByOne("C:\\Users\\test\\Desktop\\Result", listCb, 720, 480, args[4]);
		
	}
}
